import math

from game.gui.container import Container
import pygame
from pygame.locals import *
from heapq import *

def dotproduct(v1, v2):
    return sum((a * b) for a, b in zip(v1, v2))

def length(v):
    return math.sqrt(dotproduct(v, v))

def angle(v1, v2):
    ll = length(v1) * length(v2)
    if ll == 0:
        return 0
    return math.acos(dotproduct(v1, v2) / ll)

def orient(v):
    return angle([0,1], v)

class Menu(Container):
    def __init__(self, **args):
        Container.__init__(self, **args)

        args.setdefault("gap", 0)
        args.setdefault("modal", 1)
        self.item_gap = args["gap"]
        self.modal = args["modal"]

        self.menu_items = []


    def add_item(self, btn):

        #find out where to position the new item
        vpos = 0
        for i in menu_items:
            vpos += i.rect[3] + self.item_gap

        btn.rect[3] = vpos
        self.menu_items.append(btn)
        


#radial menu is split into 8 sectors, north, east, south, west, ne, nw, se, sw,
#each sector is 45 degrees, and relate to the compass orientations
class RadialMenu(Menu):
    def __init__(self, **args):
        Menu.__init__(self, **args)
        self.menu_items = [None for i in xrange(8)]
        
        self.NORTH = 0
        self.NORTHEAST = 1
        self.EAST = 2
        self.SOUTHEAST = 3
        self.SOUTH = 4
        self.SOUTHWEST = 5
        self.WEST = 6
        self.NORTHWEST = 7

        self.pos_south = math.pi / 8
        self.pos_southew = (math.pi / 8) * 3
        self.pos_eastwest = (math.pi / 8) * 5
        self.pos_northew = (math.pi / 8) * 7

        self.size = 16
        self.pad = 5

    def add_item(self, btn, pos=0):
        btn.parent = self
        heappush(self.children, (0, btn))
        self.menu_items[pos] = btn
        if pos == self.NORTH:
            #xp, yp = self.rect.centerx - (self.size // 2), self.rect.centery - (self.rect.height // 2) + self.pad
            xp, yp = (self.rect.width // 2) - (self.size // 2), self.pad
        elif pos == self.NORTHEAST:
            #xp, yp = self.rect.centerx + (self.rect.width // 4) - (self.size // 2) + self.pad, self.rect.centery - (self.rect.height // 4) - (self.size // 2) - self.pad
            xp, yp = self.rect.width - (self.rect.width // 4) - (self.size // 2) + self.pad, (self.rect.height // 4) - (self.size // 2) - self.pad
        elif pos == self.EAST:
            #xp, yp = self.rect.centerx + (self.rect.width // 2) - self.size - self.pad, self.rect.centery - (self.size // 2)
            xp, yp = self.rect.width - self.size - self.pad, (self.rect.height // 2) - (self.size // 2)
        elif pos == self.SOUTHEAST:
            #xp, yp = self.rect.centerx + (self.rect.width // 4) - (self.size // 2) + self.pad, self.rect.centery + (self.rect.height // 4) - (self.size // 2) + self.pad
            xp, yp = self.rect.width - (self.rect.width // 4) - (self.size // 2) + self.pad, self.rect.height - (self.rect.height // 4) - (self.size // 2) + self.pad
        elif pos == self.SOUTH:
            #xp, yp = self.rect.centerx - (self.size // 2), self.rect.centery + (self.rect.height // 2) - self.size - self.pad
            xp, yp = (self.rect.width // 2) - (self.size // 2), self.rect.height - self.size - self.pad
        elif pos == self.SOUTHWEST:
            #xp, yp = self.rect.centerx - (self.rect.width // 4) - (self.size // 2) - self.pad, self.rect.centery + (self.rect.height // 4) - (self.size // 2) + self.pad
            xp, yp = (self.rect.width // 4) - (self.size // 2) - self.pad, self.rect.height - (self.rect.height // 4) - (self.size // 2) + self.pad
        elif pos == self.WEST:
            #xp, yp = self.rect.centerx - (self.rect.width // 2) + self.pad, self.rect.centery - (self.size // 2)
            xp, yp = self.pad, (self.rect.height // 2) - (self.size // 2)
        elif pos == self.NORTHWEST:
            #xp, yp = self.rect.centerx - (self.rect.width // 4) - (self.size // 2) - self.pad, self.rect.centery - (self.rect.height // 4) - (self.size // 2) - self.pad
            xp, yp = (self.rect.width // 4) - (self.size // 2) - self.pad, (self.rect.height // 4) - (self.size // 2) - self.pad

        btn.rect.topleft = xp, yp
        self.make_dirty()
        #north

    def receive(self, dat, evt):
        if evt.type == MOUSEBUTTONDOWN:
            pos_global = evt.pos
            if not self.rect.collidepoint(pos_global):
                print 'kill me'
                self.parent.remove_child(self)
                return 1
            
        if evt.type == MOUSEMOTION:
            pos_global = evt.pos
            #pos_local = (pos_global[0] - self.rect[0], pos_global[1] - self.rect[1])
            #no collision, nothing is hovered

            for i in self.menu_items:
                if i is not None:
                    i.change_state('idle')
            if not self.rect.collidepoint(pos_global):
                return 0
            #collision, find which radial button
            else:
                p = [b - a for a, b in zip(self.rect.center, pos_global)]
                op = orient(p)
                west = p[0] < 0
                dist = pow(p[0],2) + pow(p[1],2)
                #print dist
                if dist > 1024 and dist < 3600:
                    b = None
                    if op < self.pos_south:
                        #print 's'
                        b = self.menu_items[self.SOUTH]
                    elif op < self.pos_southew:
                        if west:
                            #print 'sw'
                            b = self.menu_items[self.SOUTHWEST]
                        else:
                            #print 'se'
                            b = self.menu_items[self.SOUTHEAST]
                    elif op < self.pos_eastwest:
                        if west:
                            #print 'w'
                            b = self.menu_items[self.WEST]
                        else:
                            #print 'e'
                            b = self.menu_items[self.EAST]
                    elif op < self.pos_northew:
                        if west:
                            #print 'nw'
                            b = self.menu_items[self.NORTHWEST]
                        else:
                            #print 'ne'
                            b = self.menu_items[self.NORTHEAST]
                    else:
                        #print 'n'
                        b = self.menu_items[self.NORTH]

                    if b is not None:
                        b.change_state('hover')
                return 1

        return self.modal




